/******************************************************************************\
    Auxiliary.h contains plugin-depended functions.
    It's used with acm server plugins. See DllMain.cpp for details.
    Copyright (C) 2008  Victor Vinogradov (fly3333@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
\******************************************************************************/

#pragma once

#include <string>
#include <map>
#include <vector>
#include <Common\Memory.hpp>
#include "..\Additions.h"

struct sProblem
{
	unsigned long Id;
	unsigned long Key;
	unsigned long Category;
	std::string Header;
	bool IsLoaded;
	std::string Body;
	std::vector< unsigned long > AdditionId;
	sProblem( unsigned long id, unsigned long key, unsigned long category, const std::string &header )
		: Id( id )
		, Key( key )
		, Category( category )
		, Header( header )
		, IsLoaded( false )
	{
	}
	sProblem( const sProblem &problem )
		: Id( problem.Id )
		, Key( problem.Key )
		, Category( problem.Category )
		, Header( problem.Header )
		, IsLoaded( problem.IsLoaded )
		, Body( problem.Body )
		, AdditionId( problem.AdditionId )
	{
	}
	sProblem &operator =( const sProblem &problem )
	{
		Id = problem.Id;
		Key = problem.Key;
		Category = problem.Category;
		Header = problem.Header;
		IsLoaded = problem.IsLoaded;
		Body = problem.Body;
		AdditionId = problem.AdditionId;
		return *this;
	}
	bool Load();
};

struct sLanguage
{
	unsigned long Id;
	std::string Title;
	sLanguage( unsigned long id, const std::string &title )
		: Id( id )
		, Title( title )
	{
	}
	sLanguage( const sLanguage &language )
		: Id( language.Id )
		, Title( language.Title )
	{
	}
	sLanguage &operator =( const sLanguage &language )
	{
		Id = language.Id;
		Title = language.Title;
		return *this;
	}
};

extern cCriticalSection AboutCriticalSection;
extern const char Title[];
extern const char Comment[];

extern cCriticalSection LanguagesCriticalSection;
extern std::map< unsigned long, unsigned long > LanguageIndex;
extern std::vector< sLanguage > Language;

extern cCriticalSection ProblemsCriticalSection;
extern std::map< unsigned long, unsigned long > ProblemIndex;
extern std::vector< sProblem > Problem;

extern cCriticalSection VariablesCriticalSection;
extern const unsigned long VariablesCount;
extern const char *VariableProperties[];
extern std::string VariableValue[];

extern cCriticalSection CompilationErrorCriticalSection;
extern std::map< unsigned long, std::string > CompilationError;

bool LoadProblems();
bool LoadLanguages();
bool SubSubmit( unsigned long problem_index, unsigned long language_index, const std::string &source, long &result, unsigned short &test_number, unsigned long &time, unsigned long &memory );
